import { useRef, memo } from 'react';
import Editor, { loader, OnValidate } from '@monaco-editor/react';
import { Space, Button, Tooltip } from 'antd';
import {
  BoldOutlined,
  ItalicOutlined,
  StrikethroughOutlined,
  OrderedListOutlined,
  UnorderedListOutlined,
  LinkOutlined,
  PictureOutlined,
  CodeOutlined,
  TableOutlined,
} from '@ant-design/icons';

// Monaco Editor 加载配置
const loaderConfig = {
  'vs/nls': {
    availableLanguages: {
      '*': 'zh-cn',
    },
  },
  paths: {
    // 根据需要调整版本和产物类型
    // https://cdn.jsdelivr.net/npm/monaco-editor@0.43.0/min/vs
    vs: 'https://gw.alipayobjects.com/os/lib/monaco-editor/0.34.0/min/vs',
  },
};
loader.config(loaderConfig);

interface MonacoEditorType {
  style?: React.CSSProperties;
  value?: string;
  onChange?: (value: string | undefined) => void;
  defaultValue?: string;
  theme?: 'vs-light' | 'vs-dark';
  onValidate?: OnValidate;
  height?: string | number;
  hideHeadingBorder?: boolean;
}

// Markdown 快捷插入项
const markdownShortcuts = [
  {
    icon: <BoldOutlined />,
    title: '粗体',
    prefix: '**',
    suffix: '**',
    placeholder: '粗体文本',
  },
  {
    icon: <ItalicOutlined />,
    title: '斜体',
    prefix: '*',
    suffix: '*',
    placeholder: '斜体文本',
  },
  {
    icon: <StrikethroughOutlined />,
    title: '删除线',
    prefix: '~~',
    suffix: '~~',
    placeholder: '删除线文本',
  },
  {
    icon: <OrderedListOutlined />,
    title: '有序列表',
    prefix: '1. ',
    suffix: '\n2. ',
    placeholder: '列表项',
    multiline: true,
  },
  {
    icon: <UnorderedListOutlined />,
    title: '无序列表',
    prefix: '- ',
    suffix: '\n- ',
    placeholder: '列表项',
    multiline: true,
  },
  {
    icon: <LinkOutlined />,
    title: '链接',
    prefix: '[',
    suffix: '](url)',
    placeholder: '链接文本',
  },
  {
    icon: <PictureOutlined />,
    title: '图片',
    prefix: '![',
    suffix: '](url)',
    placeholder: '图片描述',
  },
  {
    icon: <CodeOutlined />,
    title: '代码块',
    prefix: '```\n',
    suffix: '\n```',
    placeholder: '在此输入代码',
    multiline: true,
  },
  {
    icon: <TableOutlined />,
    title: '表格',
    prefix: '| 表头1 | 表头2 | 表头3 |\n| --- | --- | --- |\n| 内容1 | 内容2 | 内容3 |',
    suffix: '',
    placeholder: '',
    multiline: true,
  },
];

const MonacoEditor = (props: MonacoEditorType) => {
  const {
    style,
    value = '',
    onChange = () => {},
    defaultValue = '',
    theme = 'vs-light',
    height = 'calc(100vh - 432px)',
    hideHeadingBorder = false,
  } = props;

  const editorRef = useRef<any>(null);
  const lastSelectionRef = useRef<any>(null);

  // 在光标位置插入文本
  const insertText = (prefix: string, suffix: string = '', placeholder: string = '') => {
    const editor = editorRef.current;
    if (!editor) return;

    const selection = editor.getSelection();
    const model = editor.getModel();

    // 保存当前选区
    lastSelectionRef.current = selection;

    const selectedText = model.getValueInRange(selection);
    const text = selectedText || placeholder;
    const newText = `${prefix}${text}${suffix}`;

    // 执行编辑操作
    const operation = {
      range: selection,
      text: newText,
      forceMoveMarkers: true,
    };

    editor.executeEdits('markdown-shortcut', [operation]);

    // 如果没有选中文本，设置新的选区
    if (!selectedText) {
      const startLineNumber = selection.startLineNumber;
      const startColumn = selection.startColumn + prefix.length;
      const endColumn = startColumn + placeholder.length;

      editor.setSelection({
        startLineNumber,
        startColumn,
        endLineNumber: startLineNumber,
        endColumn,
      });
    }

    // 触发 onChange 事件
    const newValue = editor.getValue();
    onChange(newValue);

    // 确保编辑器保持焦点
    setTimeout(() => {
      editor.focus();
    }, 0);
  };

  const handleEditorDidMount = (editor: any) => {
    editorRef.current = editor;

    // 配置编辑器
    editor.updateOptions({
      renderWhitespace: 'none',
      wordWrap: 'on',
      lineNumbers: 'on',
      scrollBeyondLastLine: false,
      minimap: { enabled: false },
      contextmenu: true,
      folding: true,
      padding: { top: 10, bottom: 10 },
      suggest: {
        snippetsPreventQuickSuggestions: false,
      },
    });
  };

  return (
    <div
      style={{
        width: '100%',
        marginBottom: 10,
        height,
        minHeight: '300px',
        position: 'relative',
        border: '1px solid #d9d9d9',
        borderRadius: 4,
        overflowY: 'auto',
        ...style,
      }}
    >
      <div className="bg-white p-2 mb-2 flex items-center space-x-1">
        <Space wrap>
          {markdownShortcuts.map((item, index) => (
            <Tooltip
              key={index}
              title={item.title}
            >
              <Button
                type="text"
                icon={item.icon}
                onClick={() => insertText(item.prefix, item.suffix, item.placeholder)}
              />
            </Tooltip>
          ))}
        </Space>
      </div>
      <Editor
        height="calc(100% - 60px)"
        language="markdown"
        theme={theme}
        defaultValue={defaultValue}
        value={value}
        onMount={handleEditorDidMount}
        onChange={onChange}
        options={{
          automaticLayout: true,
          overviewRulerBorder: false,
          renderLineHighlight: 'all',
          fontFamily: 'Menlo, Monaco, "Courier New", monospace',
          fontSize: 14,
          lineHeight: 1.5,
        }}
        className={`monaco-editor-container ${hideHeadingBorder ? 'hide-heading-border' : ''}`}
      />
      {hideHeadingBorder && (
        <style>
          {`
            .hide-heading-border .markdown-body h1,
            .hide-heading-border .markdown-body h2,
            .hide-heading-border .markdown-body h3,
            .hide-heading-border .markdown-body h4,
            .hide-heading-border .markdown-body h5,
            .hide-heading-border .markdown-body h6 {
              border-bottom: none !important;
              padding-bottom: 0 !important;
              margin-bottom: 16px !important;
            }
          `}
        </style>
      )}
    </div>
  );
};

export default memo(MonacoEditor);
